﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ControlCenter.Model;
using ControlCenter.Model.BizEntities;
using ControlCenter.Operation;
using MingYuanYun.Context.Abstractions;
using MingYuanYun.Exception;
using MingYuanYun.Utility;

namespace ControlCenter.ApplicationService
{
    /// <summary>
    /// 参数服务类
    /// </summary>
    public class ParamService : ApplicationServiceBase, IParamService
    {
        private readonly IParamSettingOperation _iParamSettingOperation;

        public const string CODE_ErpApiParam = "ErpApiParam";
        public const string CODE_RobotVersionParam = "RobotVersionParam";
        public const string CODE_ExecutionCycleParam = "ExecutionCycleParam";

        /// <summary>
        /// 类初始化
        /// </summary>
        /// <param name="context"></param>
        public ParamService(IServiceContext context) : base(context)
        {
            _iParamSettingOperation = this.GetService<IParamSettingOperation>();
        }

        /// <summary>
        /// 获取ERP配置信息
        /// </summary>
        /// <returns></returns>
        public async Task<ErpApiParam> GetErpApiParam()
        {
            return await GetParam<ErpApiParam>(CODE_ErpApiParam);
        }

        /// <summary>
        /// 获取机器人最新版本信息
        /// </summary>
        /// <returns></returns>
        public async Task<RobotVersionParam> GetRobotVersionParam()
        {
            return await GetParam<RobotVersionParam>(CODE_RobotVersionParam);
        }

        /// <summary>
        /// 获取执行周期设置
        /// </summary>
        /// <returns></returns>
        public async Task<List<ExecutionCycleParam>> GetExecutionCycleParam()
        {
            return await GetParam<List<ExecutionCycleParam>>(CODE_ExecutionCycleParam);
        }

        /// <summary>
        /// 通过参数CODE读取配置，返回配置类
        /// </summary>
        /// <typeparam name="T">参数类</typeparam>
        /// <param name="paramCode">参数CODE</param>
        /// <returns></returns>
        public async Task<T> GetParam<T>(string paramCode)
        {
            var paramSetting = await _iParamSettingOperation.Find(paramCode);
            if (paramSetting == null)
            {
                return default(T);
            }
            return Utils.JsonToObject<T>(paramSetting.Value);
        }

        /// <summary>
        /// 通过参数CODE读取配置，返回配置JSON串
        /// </summary>
        /// <param name="paramCode">参数CODE</param>
        /// <returns></returns>
        public async Task<string> GetParam(string paramCode)
        {
            //参数校验
            ExceptionAssert.IsNullOrEmpty(paramCode, $"{nameof(paramCode)} 不能为空");

            //从数据库中查询数据
            var paramSetting = await _iParamSettingOperation.Find(paramCode);
            if (paramSetting == null)
            {
                return "{}";
            }
            return paramSetting.Value;
        }

        /// <summary>
        /// 更新执行周期设置
        /// </summary>
        /// <param name="paramDto">请求参数DTO</param>
        /// <returns></returns>
        public async Task UpdateExecutionCycleParam(List<ExecutionCycleParam> paramDto)
        {
            //参数校验
            ValidateUpdateExecutionCycleParam(paramDto);

            await UpdateParam(CODE_ExecutionCycleParam, paramDto);
        }

        /// <summary>
        /// 更新机器人版本信息
        /// </summary>
        /// <param name="paramDto">请求参数DTO</param>
        /// <returns></returns>
        public async Task UpdateRobotVersionParam(RobotVersionParam paramDto)
        {
            ValidateUpdateRobotVersionParam(paramDto);

            await UpdateParam(CODE_RobotVersionParam, paramDto);
        }

        /// <summary>
        /// 更新ERP配置信息
        /// </summary>
        /// <param name="paramDto">请求参数DTO</param>
        /// <returns></returns>
        public async Task UpdateErpApiParam(ErpApiParam paramDto)
        {
            ExceptionAssert.IsNull(paramDto, nameof(paramDto));

            await UpdateParam(CODE_ErpApiParam, paramDto);
        }

        #region 私有方法
        /// <summary>
        /// 更新执行周期设置前参数校验
        /// </summary>
        /// <param name="paramDto"></param>
        private void ValidateUpdateExecutionCycleParam(List<ExecutionCycleParam> paramDto)
        {
            ExceptionAssert.IsNull(paramDto, nameof(paramDto));

            paramDto.ForEach(p =>
            {
                ExceptionAssert.IsTrue(string.IsNullOrEmpty(p.Name) || string.IsNullOrEmpty(p.Cron), "名称或表达式有空值");
            });
        }

        /// <summary>
        /// 更新机器人版本信息前参数校验
        /// </summary>
        /// <param name="paramDto"></param>
        private void ValidateUpdateRobotVersionParam(RobotVersionParam paramDto)
        {
            ExceptionAssert.IsNull(paramDto, nameof(paramDto));
            ExceptionAssert.IsNullOrEmpty(paramDto.Version, "版本号不能为空");
            ExceptionAssert.IsNullOrEmpty(paramDto.UpdateTime, "更新日期不能为空");
            ExceptionAssert.IsNullOrEmpty(paramDto.DownloadUrl, "下载地址不能为空");
        }

        /// <summary>
        /// 更新业务参数
        /// </summary>
        /// <param name="paramCode"></param>
        /// <param name="obj"></param>
        /// <returns></returns>
        private async Task UpdateParam(string paramCode, object obj)
        {
            var saveParam = new ParamSettings
            {
                ParamCode = paramCode,
                Value = Utils.ObjectToJson(obj)
            };
            await _iParamSettingOperation.UpdateOrSave(saveParam);
        }
        #endregion
    }
}
